﻿/**
 * @file std_bitset.h
 * Copyright (c) 2024 Gaaagaa. All rights reserved.
 * 
 * @author  : Gaaagaa
 * @date    : 2024-08-28
 * @version : 1.0.0.0
 * @brief   : 使用 C API 的接口形式实现 位集（位图） 操作类。
 */

/**
 * The MIT License (MIT)
 * Copyright (c) Gaaagaa. All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef __STD_BITSET_H__
#define __STD_BITSET_H__

#include "std_comm.h"

////////////////////////////////////////////////////////////////////////////////

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

////////////////////////////////////////////////////////////////////////////////

//====================================================================

// 
// xstd_bitset_t 的相关数据类型定义
// 

#define XBS_FALSE              XSTD_FALSE
#define XBS_TRUE               XSTD_TRUE
#define XBS_NULL               XSTD_NULL

typedef xstd_void_t            xbs_void_t;
typedef xstd_bool_t            xbs_bool_t;
typedef xstd_size_t            xbs_size_t;
typedef xstd_ctxt_t            xbs_ctxt_t;

/** 声明 xstd_bitset_t 对象 句柄（this指针）类型 */
typedef struct xstd_bitset_t * xbs_this_t;

/** 声明 xstd_bitset_t 的位索引类型 */
typedef xbs_size_t             xbs_ipos_t;

/** 定义 起始位 的 位索引值 */
#define XBS_IBEGIN             ((xbs_ipos_t)0)

/** 定义 结束（无效）位 的 位索引值 */
#define XBS_IEND               ((xbs_ipos_t)-1)

/**
 * @enum  xbs_mark_t
 * @brief xstd_bitset_t 位的 标识状态 枚举值。
 */
typedef enum xbs_mark_t
{
    XBS_UNMARKED = 0,  ///< 未标识
    XBS_MARKED   = 1,  ///< 已标识
} xbs_mark_t;

//====================================================================

// 
// xstd_bitset_t 的相关操作接口
// 

/**********************************************************/
/**
 * @brief 返回内部的 sizeof(xstd_bitset_t) 值。
 */
xbs_size_t std_bitset_sizeof(void);

/**********************************************************/
/**
 * @brief 创建 xstd_bitset_t 对象。
 * @note 
 * 1. 入参 xbs_ctxt 中的 内存管理对象，若其中的某个回调函数
 *    为 XBS_NULL，则配置成全局管理对象对应函数接口。
 * 2. 可使用 @see std_bitset_destroy() 销毁对象。
 * 3. 忽略 xbs_ctxt 中的 xstd_etype、xstd_esize 两个字段的设定值。
 * 
 * @param [in ] xbs_ctxt : 所存储位的类型上下文描述信息（若为 XBS_NULL，则取内部默认值）。
 * @param [in ] xst_size : 位数量。
 * 
 * @return xbs_this_t : xstd_bitset_t 对象句柄。
 */
xbs_this_t std_bitset_create(xbs_ctxt_t xbs_ctxt, xbs_size_t xst_size);

/**********************************************************/
/**
 * @brief 销毁 xstd_bitset_t 对象，其由 @see std_bitset_create() 创建。
 */
xbs_void_t std_bitset_destroy(xbs_this_t xbs_this);

/**********************************************************/
/**
 * @brief 创建 xstd_bitset_t 对象。
 * @note 
 * 1. 入参 xbs_ctxt 中的 内存管理对象，若其中的某个回调函数
 *    为 XBS_NULL，则配置成全局管理对象对应函数接口。
 * 2. 可使用 @see std_bitset_emplace_destroy() 销毁对象。
 * 3. 忽略 xbs_ctxt 中的 xstd_etype、xstd_esize 两个字段的设定值。
 * 
 * @param [in,out] xbs_this : 
 * 存储 xstd_bitset_t 对象的缓存，
 * 其大小不可小于 std_bitset_sizeof() 的返回值。
 * 
 * @param [in    ] xbs_ctxt : 所存储位的类型上下文描述信息（若为 XBS_NULL，则取内部默认值）。
 * @param [in    ] xst_size : 位数量。
 * 
 * @return xbs_this_t : xstd_bitset_t 对象句柄。
 */
xbs_this_t std_bitset_emplace_create(
                xbs_this_t xbs_this,
                xbs_ctxt_t xbs_ctxt,
                xbs_size_t xst_size);

/**********************************************************/
/**
 * @brief 在指定缓存上销毁 xstd_bitset_t 对象。
 * @note  xstd_bitset_t 对象是由 @see std_bitset_emplace_create() 创建。
 */
xbs_void_t std_bitset_emplace_destroy(xbs_this_t xbs_this);

/**********************************************************/
/**
 * @brief 判断 xstd_bitset_t 对象是否有 已标识状态 的位。
 */
xbs_bool_t std_bitset_any(xbs_this_t xbs_this);

/**********************************************************/
/**
 * @brief 判断 xstd_bitset_t 对象的 所有位 是否都是 未标识状态。
 */
xbs_bool_t std_bitset_none(xbs_this_t xbs_this);

/**********************************************************/
/**
 * @brief 判断 xstd_bitset_t 对象的 所有位 是否都是 已标识状态。
 */
xbs_bool_t std_bitset_all(xbs_this_t xbs_this);

/**********************************************************/
/**
 * @brief 统计 xstd_bitset_t 对象 已标识位 的数量。
 */
xbs_size_t std_bitset_count(xbs_this_t xbs_this);

/**********************************************************/
/**
 * @brief 返回 xstd_bitset_t 对象的 位容量。
 */
xbs_size_t std_bitset_size(xbs_this_t xbs_this);

/**********************************************************/
/**
 * @brief 获取 xstd_bitset_t 对象指定位的 位标识状态。
 * 
 * @param [in ] xbs_this : xstd_bitset_t 对象。
 * @param [in ] xbs_ipos : 指定位的 位索引。
 * 
 * @return xbs_mark_t : 标识状态值。可参看 @see xbs_mark_t 相关枚举值。
 */
xbs_mark_t std_bitset_at(xbs_this_t xbs_this, xbs_ipos_t xbs_ipos);

/**********************************************************/
/**
 * @brief 重置 xstd_bitset_t 对象的所有位 为 未标识状态。
 */
xbs_void_t std_bitset_reset(xbs_this_t xbs_this);

/**********************************************************/
/**
 * @brief 测试 xstd_bitset_t 对象中 指定位 的 标识状态。
 * 
 * @param [in ] xbs_this : xstd_bitset_t 对象。
 * @param [in ] xbs_ipos : 测试位的 位索引。
 * @param [in ] xbs_mark : 测试的 标识状态。
 * 
 * @return xbs_bool_t : 测试位 的标识状态，是否与 测试状态 一致。
 */
xbs_bool_t std_bitset_testi(
                xbs_this_t xbs_this,
                xbs_ipos_t xbs_ipos,
                xbs_mark_t xbs_mark);

/**********************************************************/
/**
 * @brief 测试 xstd_bitset_t 对象 区间 [ xbs_ibgn, xbs_iend ) 的 位标识状态。
 * 
 * @param [in ] xbs_this : xstd_bitset_t 对象。
 * @param [in ] xbs_ibgn : 测试区间 的 起始位索引。
 * @param [in ] xbs_iend : 测试区间 的 结束位索引。
 * @param [in ] xbs_mark : 测试的 标识状态。
 * 
 * @return xbs_size_t : 
 * 返回 通过测试 的 位数量，其意义可理解为
 * 区间 [ xbs_ibgn, xbs_ibgn + 返回值 ) 的 位状态 均为 xbs_mark 。
 * 当然 返回值 为 0 时，表示 没有任何一位 通过测试。
 */
xbs_size_t std_bitset_testn(
                xbs_this_t xbs_this,
                xbs_ipos_t xbs_ibgn,
                xbs_ipos_t xbs_iend,
                xbs_mark_t xbs_mark);

/**********************************************************/
/**
 * @brief 设置 xstd_bitset_t 对象的 位标识状态。
 * @note  要求所设置位，其当前 标识状态 与 设置的状态 相反。
 * 
 * @param [in,out] xbs_this : xstd_bitset_t 对象。
 * @param [in    ] xbs_ipos : 操作位 的 位索引。
 * @param [in    ] xbs_mark : 设置的 标识状态。
 * 
 * @return xbs_bool_t : 操作是否成功。
 */
xbs_bool_t std_bitset_marki(
                xbs_this_t xbs_this,
                xbs_ipos_t xbs_ipos,
                xbs_mark_t xbs_mark);

/**********************************************************/
/**
 * @brief 设置 xstd_bitset_t 对象区间 [ xbs_ibgn, xbs_iend ) 的 位标识状态。
 * @note  要求所设置的所有位，其当前 标识状态 与 设置的状态 相反。
 * 
 * @param [in,out] xbs_this : xstd_bitset_t 对象。
 * @param [in    ] xbs_ibgn : 操作区间 的 起始位索引。
 * @param [in    ] xbs_iend : 操作区间 的 结束位索引。
 * @param [in    ] xbs_mark : 设置的 标识状态。
 * 
 * @return xbs_bool_t : 操作是否成功。
 */
xbs_bool_t std_bitset_markn(
                xbs_this_t xbs_this,
                xbs_ipos_t xbs_ibgn,
                xbs_ipos_t xbs_iend,
                xbs_mark_t xbs_mark);

/**********************************************************/
/**
 * @brief 对 xstd_bitset_t 对象指定位 进行 标识状态 反转。
 * 
 * @param [in,out] xbs_this : xstd_bitset_t 对象。
 * @param [in    ] xbs_ipos : 操作位 的 位索引。
 */
xbs_void_t std_bitset_flipi(
            xbs_this_t xbs_this,
            xbs_ipos_t xbs_ipos);

/**********************************************************/
/**
 * @brief 对 xstd_bitset_t 对象区间 [ xbs_ibgn, xbs_iend ) 进行 标识状态 反转。
 * 
 * @param [in,out] xbs_this : xstd_bitset_t 对象。
 * @param [in    ] xbs_ibgn : 操作区间 的 起始位索引。
 * @param [in    ] xbs_iend : 操作区间 的 结束位索引。
 */
xbs_void_t std_bitset_flipn(
                xbs_this_t xbs_this,
                xbs_ipos_t xbs_ibgn,
                xbs_ipos_t xbs_iend);

/**********************************************************/
/**
 * @brief 在 xstd_bitset_t 对象中，从 xbs_ipos 位开始查找 符合 xbs_mark 标识状态的位。
 * 
 * @param [in ] xbs_this : xstd_bitset_t 对象。
 * @param [in ] xbs_ipos : 查找操作的 起始位索引。
 * @param [in ] xbs_mark : 指定查找的 位标识状态。
 * 
 * @return xbs_ipos_t : 返回符合状态的 位索引；失败时返回 XBS_IEND 。
 */
xbs_ipos_t std_bitset_findi(
                xbs_this_t xbs_this,
                xbs_ipos_t xbs_ipos,
                xbs_mark_t xbs_mark);

/**********************************************************/
/**
 * @brief 
 * 在 xstd_bitset_t 对象中，从 xbs_ipos 位开始查找
 * 连续 xst_nbit 个符合 xbs_mark 标识状态的位。
 * 
 * @param [in ] xbs_this : xstd_bitset_t 对象。
 * @param [in ] xbs_ipos : 查找操作的 起始位索引。
 * @param [in ] xst_nbit : 查找符合 标识状态 的 位 的数量。
 * @param [in ] xbs_mark : 指定查找的 位标识状态。
 * 
 * @return xbs_ipos_t : 
 * 返回符合状态的 起始位索引，即区间 [ 返回的位索引, 返回的位索引 + xst_nbit )
 * 符合 xbs_mark 标识状态；而返回 XBS_IEND 时，表示查找失败。
 */
xbs_ipos_t std_bitset_findn(
                xbs_this_t xbs_this,
                xbs_ipos_t xbs_ipos,
                xbs_size_t xst_nbit,
                xbs_mark_t xbs_mark);

////////////////////////////////////////////////////////////////////////////////

#ifdef __cplusplus
}; // extern "C"
#endif // __cplusplus

////////////////////////////////////////////////////////////////////////////////

#endif // __STD_BITSET_H__
